import java.awt.Point;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;

import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.JOptionPane;

public class Generator implements Runnable {

	Point pos = new Point(0, 0);
	Sudoku sudoku;
	int speed;
	Thread thread;
	boolean generated;
	Random rand = new Random();
	static boolean fertig = false;
	sfx sounds = new sfx();

	public Generator(Sudoku su, int sp) {
		sudoku = su;
		speed = sp;
		if (speed < 0)
			speed = 0;
		speed *= 50;
	}

	public void run() {
		while (!generated)
		{
			oneLoop();
		}
		fertig = true;
		System.out.println("run:" + fertig);
		System.out.println("GENERATED!!");
		sudoku.running = null;
		try {
			sudoku.saveTemp1();
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		sudoku.auswahl_schwierigkeit();
	
		try {
			sounds.play(2);
		} catch (UnsupportedAudioFileException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (LineUnavailableException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		sudoku.resetTime();
		sudoku.startTime();
		thread.stop();
		//sudoku.auswahl_schwierigkeit();

	}
	

	private void oneLoop() {
		// update lil
		generated = true;
		for (int j = 0; j < 9; j++) {
			for (int i = 0; i < 9; i++) {
				sudoku.cursor.x = i;
				sudoku.cursor.y = j;
				if (sudoku.nums[i][j] > 0)
					continue;
				//System.out.println(i + " " + j);
				ArrayList<Integer> l = getLil(i, j);
				if (l.size() > 0)
					sudoku.nums[i][j] = l.get(new Random().nextInt(l.size()));
				else {
					for (int i1 = 0; i1 < 6; i1++) {
						if (i == 0) {
							i = 9;
							j--;
						}
						i--;
						sudoku.nums[i][j] = 0;
					}
					generated = false;
					return;
				}
				//sleep();
			}
		}

	}

	private void sleep() {
		try {
			thread.sleep(speed);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	private ArrayList<Integer> getLil(int x, int y) {
		ArrayList<Integer> al = new ArrayList<Integer>();
		ArrayList<Integer> lx = getLilX(x);
		ArrayList<Integer> ly = getLilY(y);
		ArrayList<Integer> lb = getLilBox(x, y);

		for (int i = 1; i <= 9; i++) {
			if (lx.contains(i) && ly.contains(i) && lb.contains(i))
				al.add(i);
		}
		return al;
	}

	private ArrayList<Integer> getLilX(int x) {
		ArrayList<Integer> al = new ArrayList<Integer>();
		for (int i = 1; i <= 9; i++)
			al.add(i);

		for (int j = 0; j < 9; j++) {
			if (sudoku.nums[x][j] > 0)
				al.remove((Object) sudoku.nums[x][j]);
		}
		return al;
	}

	private ArrayList<Integer> getLilY(int y) {
		ArrayList<Integer> al = new ArrayList<Integer>();
		for (int i = 1; i <= 9; i++)
			al.add(i);

		for (int i = 0; i < 9; i++) {
			if (sudoku.nums[i][y] > 0)
				al.remove((Object) sudoku.nums[i][y]);
		}
		return al;
	}

	private ArrayList<Integer> getLilBox(int x, int y) {
		ArrayList<Integer> al = new ArrayList<Integer>();
		for (int i = 1; i <= 9; i++)
			al.add(i);
		// get Box
		int sx = 0, sy = 0;
		if (x > 5)
			sx = 6;
		else if (x > 2)
			sx = 3;
		if (y > 5)
			sy = 6;
		else if (y > 2)
			sy = 3;
		// check
		for (int i1 = 0, i = 0; i1 < 3; i1++) {
			for (int j = 0; j < 3; j++) {
				if (sudoku.nums[sx + i][sy + j] > 0)
					al.remove((Object) sudoku.nums[sx + i][sy + j]);
			}
			i++;
		}
		//System.out.println(sx + "x" + sy + " " + al);
		return al;
	}

	public static void maze(Sudoku s, int del) {
		Random rand = new Random();
		for (int i = 0; i < del; i++) {
			int x = rand.nextInt(9);
			int y = rand.nextInt(9);
			if (s.nums[x][y] > 0)
				s.nums[x][y] = 0;
			else {
				i--;
				continue;
			}
		}
	}
}
